#!/usr/bin/python
# coding:utf-8

from flask import request, url_for
from flask_restplus import Resource, Api, fields, reqparse


def init_app(app, prefix='/rest'):
    api = Api(app, prefix=prefix, version='1.0', title='TodoMVC API', description='A simple TodoMVC API')

    ns = api.namespace('usr', description='TODO operations')

    user = api.model('User', {
        'id': fields.String(readOnly=True, description='The user unique identifier'),
        'name': fields.String(required=True, description='The user\'s name')
    })

    class UserDAO(object):
        def __init__(self):
            self.counter = 0
            self.users = []

        def get(self, uid):
            for u in self.users:
                if u['id'] == uid:
                    return u
            api.abort(404, "User {} doesn't exist".format(uid))

        def create(self, data):
            u = data
            idx = self.counter = self.counter + 1
            u['id'] = str(idx)
            self.users.append(u)
            return u

        def update(self, uid, data):
            u = self.get(uid)
            u.update(data)
            return u

        def delete(self, uid):
            u = self.get(uid)
            self.users.remove(u)

    dao = UserDAO()
    dao.create({'name': '张三'})
    dao.create({'name': '李四'})
    dao.create({'name': 'Jack'})

    @ns.route('/')
    class UserList(Resource):
        # Shows a list of all users, and lets you POST to add new users

        @ns.doc('list_users')
        @ns.marshal_list_with(user)
        def get(self):
            # List all users
            return dao.users

        @ns.doc('create_user')
        @ns.expect(user)
        @ns.marshal_with(user, code=201)
        def post(self):
            # Create a new user
            return dao.create(api.payload), 201

    @ns.route('/<string:uid>')
    @ns.response(404, 'User not found')
    @ns.param('uid', 'The user identifier')
    class User(Resource):
        # Show a single user item and lets you delete them

        @ns.doc('get_user')
        @ns.marshal_with(user)
        def get(self, uid):
            # Fetch a given resource
            return dao.get(uid)

        @ns.doc('delete_user')
        @ns.response(204, 'User deleted')
        def delete(self, uid):
            # Delete a user given its identifier
            dao.delete(uid)
            return '', 204

        @ns.expect(user)
        @ns.marshal_with(user)
        def put(self, uid):
            # Update a user given its identifier
            return dao.update(uid, api.payload)

    hello_model = api.model('HelloModel', {
        'name': fields.String,
        'id': fields.Integer
    })

    hello_parser = reqparse.RequestParser()
    hello_parser.add_argument('id', type=int, required=True, help='id must be set at queries -- {error_msg}')
    hello_parser.add_argument('kw', required=True, help='id must be set at queries')

    @ns.route('/hello/<int:id>', endpoint='todo_ep')
    # @ns.doc(params={'id': 'An ID'})
    class HelloWorld(Resource):
        name = 'YANG'

        @ns.marshal_with(hello_model, mask='id')
        @api.expect(hello_parser)
        def get(self, id):

            # args = hello_parser.parse_args()
            # print(args)

            return {'hello': self.name, 'name': self.name, 'id': id}

        @ns.marshal_with(hello_model)
        def put(self, id):
            # args = hello_parser.parse_args()
            # print(args)

            name = request.json.get('name')
            self.name = name
            return request.json

